package com.pointmi.controller;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.pointmi.customeraccountdao.Customer;
import com.pointmi.customeraccountservice.CustomerAccountService;
import com.pointmi.loyaltydao.Loyalty;
import com.pointmi.loyaltyservice.LoyaltyService;
import com.pointmi.merchantdao.Merchant;
import com.pointmi.merchantservice.MerchantService;
import com.pointmi.model.TransactionModel;
import com.pointmi.transactiondao.Transaction;
import com.pointmi.transactionservice.TransactionService;
import com.pointmi.util.Utility;

@Controller
public class TransactionController {

	public static final String TRANSACTION_VIEW_MODEL = "transaction";
	
	@Autowired
	@Qualifier("transactionService")
	private TransactionService transactionService;
	
	@Autowired
	@Qualifier("customerService")
	private CustomerAccountService customerAccountService;
	
	@Autowired
	@Qualifier("merchantService")
	private MerchantService merchantService;
	
	@Autowired
	@Qualifier("loyaltyService")
	private LoyaltyService loyaltyService;
	
	@RequestMapping(value="/transaction.do")
	public String processTransaction(Model model)
	{
		model.addAttribute("transaction", new TransactionModel());
		return "transaction";
	}
	
	@RequestMapping(value="/transaction.do", method = RequestMethod.POST)
	public String getTransaction(@Valid TransactionModel transaction, BindingResult result, Model model)
	{
		if(!result.hasErrors())
		{
			Customer findCustomer = customerAccountService.findCustomerByEmailOrCustomerId("", transaction.getcustomerid());
			if(findCustomer != null)
			{
				Loyalty getLoyaltyByCustomer = loyaltyService.checkLoyalty(findCustomer.getCustomerId());
				if(getLoyaltyByCustomer == null)
				{
					saveNewLoyalty(transaction, findCustomer);
				}
				updateLoyalty(transaction, findCustomer, getLoyaltyByCustomer);
				saveTransaction(transaction, findCustomer);
				return "success";
			}
			return "transaction";
		}
		//redisplay the form if there is error
		return "transaction";
	}

	private void saveNewLoyalty(TransactionModel transaction,
			Customer findCustomer) {
		Loyalty newLoyalty = new Loyalty();
		newLoyalty.setCustomerId(findCustomer.getCustomerId());
		newLoyalty.setLoyaltyPoint(calculateLoyalty(transaction));
		newLoyalty.setAmountEquivalent(calculateLoyalty(transaction) * 10);
		newLoyalty.setLoyaltyExpiryDate(Utility.currentDate);
		loyaltyService.saveOrUpdate(newLoyalty);
	}

	private void updateLoyalty(TransactionModel transaction, Customer findCustomer, Loyalty getLoyaltyByCustomer) {
		int newLoyaltyPoint = calculateLoyalty(transaction);
		int oldLoyaltyPoint = getLoyaltyByCustomer.getLoyaltyPoint();
		double oldAmountEquivalent = getLoyaltyByCustomer.getAmountEquivalent();
		double newAmountEquivalent = newLoyaltyPoint * 10; //new loyalty point multiplied by 10
				
		getLoyaltyByCustomer.setCustomerId(findCustomer.getCustomerId());
		getLoyaltyByCustomer.setLoyaltyPoint(newLoyaltyPoint + oldLoyaltyPoint);
		getLoyaltyByCustomer.setAmountEquivalent(newAmountEquivalent + oldAmountEquivalent);
		getLoyaltyByCustomer.setLoyaltyExpiryDate(Utility.currentDate);
		loyaltyService.saveOrUpdate(getLoyaltyByCustomer);
	}

	private void saveTransaction(TransactionModel transaction,
			Customer findCustomer) {
		Merchant getMerchant = saveMerchant();
		Transaction newTransaction = new Transaction();
		newTransaction.setCustomerId(findCustomer.getCustomerId());
		newTransaction.setTransactionId(transaction.gettransactionid());
		newTransaction.setTransactionAmount(transaction.gettransactionamount());
		newTransaction.setMerchantId(getMerchant.getId());
		transactionService.saveOrUpdate(newTransaction);
	}
	
	private Merchant saveMerchant()
	{
		Merchant newMerchant = new Merchant();
		newMerchant.setMerchantName("Ikoyi Fuel Station");
		newMerchant.setState("Lagos");
		newMerchant.setAddress("Ikoyi Falomo");
		newMerchant.setCity("Lagos");
		newMerchant.setCountry("Nigeria");
		merchantService.saveOrUpdate(newMerchant);
		return newMerchant;
	}
	
	private int calculateLoyalty(TransactionModel model)
	{
		return (int) (model.gettransactionamount() / 100);
	}
}
